<?php
// 调用此框架前需要先定义常量：项目根目录绝对路径  ROOT_DIR
defined('ROOT_DIR') || exit('Request Error, No defined ROOT_DIR');
// 调用此框架前需要先定义常量：项目名称  APP_NAME
defined('APP_NAME') || exit('Request Error, No defined APP_NAME');

defined('SYS_DEBUG') || define('SYS_DEBUG', false);
defined('DS') || define('DS', DIRECTORY_SEPARATOR);

// 常量：框架所在目录绝对路径
defined('API_DIR') || define('API_DIR', dirname(__FILE__));
// 常量：项目所在目录绝对路径
defined('APP_DIR') || define('APP_DIR', ROOT_DIR . DS . APP_NAME);
define('MAGIC_QUOTES_GPC', get_magic_quotes_gpc());

error_reporting(SYS_DEBUG ? E_ALL : 0);
date_default_timezone_set('Asia/Shanghai');
set_magic_quotes_runtime(0);
if (SYS_DEBUG)
{
	defined('SYS_BEGIN_TIME') || define('SYS_BEGIN_TIME', microtime(true));
	require API_DIR . DS . 'vendors' . DS . 'FirePHPCore' . DS . 'FirePHP.class.php';
}

/**
 * V
 * 
 * 单例模式
 * 项目入口类，加载项目配置参数(以用户自定义参数为主，用户没有定义的参数调用框架默认参数)
 * 包含常用的方法
 *
 * @author   songhuan <iphper@yeah.net>
 * @version   $Id: Loader.php 1 2010-08-10 14:40:00Z $
 */
class V
{
	/**
	 * @var array 核心类库  名 => 地址
	 */
	public static $coreClasses = null;
	
	/**
	 * @var array 配置数据
	 */
	public static $config = null;
	
	/**
	 * @var array 提示语句
	 */
	public static $prompts = null;
	
	private static $_instance = null;
	
	/**
	 * 构造方法
	 * 加载项目配置参数
	 */
	private function __construct()
	{
		if (!array_key_exists('config', $GLOBALS)) 
			throw new Exception('App Config path is not defined');

		self::$config = require $GLOBALS['config'];
		$_config = require API_DIR . DS . 'config' . DS . 'main.php'; 
		foreach ($_config as $k => $v)
			self::$config[$k] = array_key_exists($k, self::$config) ? array_merge($v, self::$config[$k]) : $v;
		
		self::$coreClasses = require API_DIR . DS . 'config' . DS . 'coreClasses.php';
		self::$prompts = require API_DIR . DS . 'views' . DS . self::$config['web']['language'] . DS . 'prompts.php';
	}
	
	private function __clone()
	{
	}
	
	public static function getInstance()
	{
		if (null === self::$_instance) 
			self::$_instance = new self();
		
		return self::$_instance;
	}
	
	/**
	 * 自动加载类文件
	 * 
	 * @param string $classname 类名
	 * @return void
	 */
	public static function autoload($classname)
	{		
		if (array_key_exists($classname, self::$coreClasses)) 
			require API_DIR . self::$coreClasses[$classname];
		else if (strcmp(self::$config['model']['modelKey'], 
				substr($classname,-strlen(self::$config['model']['modelKey']))) === 0) 
			require self::$config['model']['modelDirectory'] . DS . $classname . '.php';
		else if (strcmp(self::$config['controller']['controllerKey'],
				substr($classname,-strlen(self::$config['controller']['controllerKey']))) === 0) 
			require self::$config['controller']['controllerDirectory'] . DS . $classname . '.php';
	}
	
	/**
	 * 享元模式
	 * 获取 Model 类实例化对象
	 * 
	 * @param string $modelname
	 * @return Model 
	 */
	public static function M($modelname)
	{
		$modelname = ucfirst($modelname) . 'Model';
		if (!Registry::has($modelname)) 
			Registry::set($modelname, new $modelname());
		
		return Registry::get($modelname);
	}
	
	/**
	 * 享元模式
	 * 获取 Db 类实例化对象
	 * 
	 * @return Database 
	 */
	public static function getDb()
	{
		if (!Registry::has('Database')) 
			Registry::set('Database', new Database());
		
		return Registry::get('Database');
	}
	
	/**
	 * 享元模式
	 * 获取 Adapter 接口子类实例化对象
	 * 
	 * @return Adapter 
	 */
	public static function getAdapter()
	{
		if (!isset(V::$config['db']['dsn'])) 
			throw new Exception('The config db > dsn is not give');
		
		if (!isset(V::$config['db']['adapter'])) 
			V::$config['db']['adapter'] = 
				ucfirst(strtolower(substr(V::$config['db']['dsn'], 0, strpos(V::$config['db']['dsn'], ':'))));
		
		$adapter = V::$config['db']['adapter'];
		if (!Registry::has($adapter)) 
			Registry::set($adapter, new $adapter());
		
		return Registry::get($adapter);
	}
	
	/**
	 * 调用FirePHP测试
	 * 
	 * @param string $Object
	 * @param string $Label
	 * @param string $Method
	 * @return void
	 */
	public static function fp($Object, $Label = 'firePHP', $Method = '')
	{
		if (!SYS_DEBUG)
			throw new Exception('The Debug is closed, FirePHP is closed');
		
		if (empty($Method)) 
			$Method = strcmp($Label, 'sql') === 0 ? 'warn' : 'log';

		$trace = debug_backtrace();
		$argLen = func_num_args();
		foreach ($trace as $v)
		{
			if ($v['class'] == 'V' && $v['function'] == 'fp' && $v['args'][0] === $Object) 
			{
				if ($argLen==1 || ($argLen==2 && $v['args'][1]===$Label) ||
					($argLen==3 && $v['args'][1]===$Label && $v['args'][2]===$Method)) 
				{
						$Label = "[{$v['file']}: {$v['line']}] $Label";
						break;
				}
			}
		}
		FirePHP::getInstance(true)->$Method($Object, $Label);
		FirePHP::getInstance(true)->error('usetime: '.(microtime(true) - SYS_BEGIN_TIME));
	}
	
}

spl_autoload_register(array('V', 'autoload'));
V::getInstance();

// 常量：语言包所在目录绝对路径
define('LANG_DIR', API_DIR . DS . 'views' . DS . V::$config['web']['language']);

switch (V::$config['session']['save_handler'])
{
	// Session存文件
	case 'default' : break;
	// Session存数据库
	case 'database' : 
		require API_DIR . DS . 'application' . DS . 'DatabaseSession.php';
		break;
	// Session存Memcache
	case 'memcache' : 
		ini_set('session.save_handler', 'memcache');
		ini_set('session.save_path', 'tcp://' . V::$config['memcache']['host'] . ':' . V::$config['memcache']['port']);
		break;
	default : 
		break;
}
